home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 3006 / 3006.xpi / components / dhConvertMgr.js < prev    next >
Text File  |  2010-01-15  |  45KB  |  1,332 lines

  1. /******************************************************************************
  2.  *            Copyright (c) 2006-2009 Michel Gutierrez. All Rights Reserved.
  3.  ******************************************************************************/
  4.  
  5. /**
  6.  * Constants.
  7.  */
  8.  
  9. const NS_CONVERT_MGR_CID = Components.ID("{5f4589e7-114b-4a4b-a63e-06ca7f22439d}");
  10. const NS_CONVERT_MGR_PROG_ID = "@downloadhelper.net/convert-manager-component";
  11. const DHNS = "http://downloadhelper.net/1.0#";
  12.  
  13. const CONV_METHOD_NONE=Components.interfaces.dhIConvertMgr.CONV_METHOD_NONE;
  14. const CONV_METHOD_UNIX=Components.interfaces.dhIConvertMgr.CONV_METHOD_UNIX;
  15. const CONV_METHOD_WIN_DH=Components.interfaces.dhIConvertMgr.CONV_METHOD_WIN_DH;
  16.  
  17. var Util=null;
  18.  
  19. /**
  20. * Object constructor
  21. */
  22. function ConvertMgr() {
  23.     try {
  24.  
  25.         this.convRulesFile = Components.classes["@mozilla.org/file/directory_service;1"]
  26.             .getService(Components.interfaces.nsIProperties)
  27.             .get("ProfD", Components.interfaces.nsIFile);
  28.         this.convRulesFile.append("dh-conv-rules.rdf");
  29.         if(this.convRulesFile.exists()) {
  30.             this.datasource=Util.getDatasourceFromRDFFile(this.convRulesFile);
  31.         } else {
  32.             var datasource=Components.classes
  33.                   ['@mozilla.org/rdf/datasource;1?name=in-memory-datasource'].
  34.                       createInstance(Components.interfaces.nsIRDFDataSource);
  35.             this.makeEmptyDataSource(datasource);
  36.             this.setDataSource(datasource);
  37.         }
  38.  
  39.         var prefService=Components.classes["@mozilla.org/preferences-service;1"]
  40.             .getService(Components.interfaces.nsIPrefService);
  41.         this.pref=prefService.getBranch("dwhelper.");
  42.         
  43.         this.promptService=Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  44.             .getService(Components.interfaces.nsIPromptService);
  45.         
  46.         this.localstore=Components.classes["@mozilla.org/rdf/datasource;1?name=local-store"]
  47.                                            .getService(Components.interfaces.nsIRDFDataSource);
  48.         this.RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService().
  49.             QueryInterface(Components.interfaces.nsIRDFService);
  50.  
  51.         this.delayQueue=[];
  52.         
  53.         this.queueDatasource=Components.classes
  54.               ['@mozilla.org/rdf/datasource;1?name=in-memory-datasource'].
  55.                   createInstance(Components.interfaces.nsIRDFDataSource);
  56.  
  57.         this.updateUnregistered();
  58.         
  59.         this.currentEntry=null;
  60.         
  61.         if(Util.getPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"conf-inited")==null) {
  62.             Util.setPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"conf-inited","true");
  63.             this.setDefaultConfigs();
  64.         }
  65.  
  66.     } catch(e) {
  67.         dump("[ConvertMgr] !!! constructor: "+e+"\n");
  68.     }
  69. }
  70.  
  71. ConvertMgr.prototype = {}
  72.  
  73. ConvertMgr.prototype.convert=function(sourceFile,targetFile,format,autoClear,listener,entry,ctx) {
  74.     //dump("[ConvertMgr] convert("+sourceFile.path+","+targetFile+","+format+")\n");
  75.     
  76.     try {
  77.  
  78.     var m=/^(.*?)\/(.*)$/.exec(format);
  79.     var extension=m[1];
  80.     var params=m[2];
  81.     
  82.     if(targetFile==null) {
  83.         targetFile=sourceFile.parent;
  84.         targetFile.append(/^(.*\.)(.*?)$/i.exec(sourceFile.leafName)[1]+extension);
  85.     }
  86.     
  87.     var convRes=Util.createNodeSR(this.queueDatasource,"urn:root",null);
  88.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"Status","2");
  89.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"InputFilePath",sourceFile.path);
  90.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"OutputFilePath",targetFile.path);
  91.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"InputFilePathShort",sourceFile.leafName);
  92.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"OutputFilePathShort",targetFile.leafName);
  93.     Util.setPropertyValueRS(this.queueDatasource,convRes,DHNS+"CreationDate",""+new Date());
  94.  
  95.     var convMethod=this.getConvMethod();
  96.     
  97.     switch(convMethod) {
  98.         case CONV_METHOD_UNIX:
  99.             this.convertUnix(sourceFile,targetFile,params,extension,convRes,autoClear,listener,entry,ctx);
  100.             break;
  101.         case CONV_METHOD_WIN_DH:
  102.             try {
  103.             if(this.checkConverterVersion()==false)
  104.                 return;
  105.             } catch(e) {
  106.                 dump("!!! checkConverterVersion: "+e+"\n");
  107.                 return;
  108.             }
  109.             this.convertDH(sourceFile,targetFile,params,extension,convRes,autoClear,listener,entry,ctx);
  110.             break;
  111.     }
  112.     
  113.     } catch(e) {
  114.         dump("!!! [ConvertMgr] convert: "+e+"\n");
  115.     }                
  116. }
  117.  
  118. ConvertMgr.prototype.setFFMPEGArgs=function(dEntry,params,sourceFile,targetFile,doTrace,doVhook) {
  119.     var pArgs=["args"];
  120.     var pParams=[params];
  121.     var passes=1;
  122.     if(/.*\/.*/.test(params)) {
  123.         pArgs.push("args2");
  124.         var m=/(.*)\/(.*)/.exec(params);
  125.         passes=2;
  126.         pParams=[m[1],m[2]];
  127.     }
  128.     for(var i=0;i<passes;i++) {
  129.         dEntry[pArgs[i]] = [ "-i", sourceFile.path,"-y","-v","0"];
  130.         dEntry[pArgs[i]]=dEntry[pArgs[i]].concat(pParams[i].split(" "));
  131.         if(doTrace) {
  132.             dEntry[pArgs[i]].push("-Xhello");
  133.             var convertTrace=false;
  134.             try {
  135.                 convertTrace=this.pref.getBoolPref("convert-helper.trace");
  136.             } catch(e) {}
  137.             if(convertTrace) {
  138.                 dEntry[pArgs[i]].push("-Xloglevel");
  139.                 var convertShowArgs=false;
  140.                 try {
  141.                     convertShowArgs=this.pref.getBoolPref("convert-helper.show-args");
  142.                 } catch(e) {}
  143.                 if(convertShowArgs)
  144.                     dEntry[pArgs[i]].push("2");
  145.                 else
  146.                     dEntry[pArgs[i]].push("1");
  147.                 var logFile=Util.getProfileDir();
  148.                 logFile.append("cvhelper.log");
  149.                 dEntry[pArgs[i]].push("-Xlogfile");
  150.                 dEntry[pArgs[i]].push(logFile.path);
  151.             }
  152.         }
  153.         if(doVhook) {
  154.             var wmFile=Util.getExtensionDir("{b9db16a4-6edc-47ec-a1f4-b86292ed211d}");
  155.             wmFile.append("local");
  156.             wmFile.append("wm.png");
  157.  
  158.             dEntry[pArgs[i]].push("-Xfn83");
  159.             dEntry[pArgs[i]].push(wmFile.path);
  160.             dEntry[pArgs[i]].push("-vhook");
  161.             dEntry[pArgs[i]].push("vhook/imlib2.dll -x 0 -y 0 -i *");
  162.         }
  163.         dEntry[pArgs[i]].push(targetFile.path);
  164.     }
  165.  
  166.     /*
  167.     dump("ffmpeg params="+dEntry.args.join(" ")+"\n");
  168.     if(dEntry.args2)
  169.         dump("ffmpeg params (pass#2)="+dEntry.args2.join(" ")+"\n");
  170.     */
  171. }
  172.  
  173. ConvertMgr.prototype.convertUnix=function(sourceFile,targetFile,params,extension,convRes,autoClear,listener,entry,ctx) {
  174.     var ffmpegFile = Components.classes["@mozilla.org/file/local;1"]
  175.         .createInstance(Components.interfaces.nsILocalFile);
  176.  
  177.     var ffmpegPath="/usr/bin/ffmpeg";
  178.     try {
  179.         ffmpegPath=this.pref.getCharPref("converter-path-ffmpeg");
  180.     } catch(e) {
  181.     }
  182.     try {
  183.         ffmpegFile.initWithPath(ffmpegPath);
  184.         if(!ffmpegFile.exists()) {
  185.             dump("!!![ConvertMgr] convert(): no ffmpeg found\n");
  186.             ffmpegFile=null;
  187.         }
  188.     } catch(e) {
  189.         dump("!!![ConvertMgr] convert(): invalid ffmpeg path\n");
  190.         ffmpegFile=null;
  191.     }
  192.     var mencoderFile = Components.classes["@mozilla.org/file/local;1"]
  193.         .createInstance(Components.interfaces.nsILocalFile);
  194.     var mencoderPath="/usr/bin/mencoder";
  195.     try {
  196.         mencoderPath=this.pref.getCharPref("converter-path-mencoder");
  197.     } catch(e) {
  198.     }
  199.     try {
  200.         mencoderFile.initWithPath(mencoderPath);
  201.         if(!mencoderFile.exists()) {
  202.             dump("!!![ConvertMgr] convert(): no mencoder found\n");
  203.             mencoderFile=null;
  204.         }
  205.     } catch(e) {
  206.         dump("!!![ConvertMgr] convert(): invalid mencoder path\n");
  207.         mencoderFile=null;
  208.     }
  209.     
  210.     if(mencoderFile==null && ffmpegFile==null) {
  211.         dump("!!![ConvertMgr] convert(): no converter found\n");
  212.     }
  213.  
  214.     var converterFile=null;
  215.     if(mencoderFile==null && ffmpegFile!=null) {
  216.         converterFile=ffmpegFile;
  217.     } else if(mencoderFile!=null && ffmpegFile==null) {
  218.         converterFile=mencoderFile;
  219.     } else {
  220.         var preferred="ffmpeg";
  221.         try {
  222.             preferred=this.pref.getCharPref("preferred-converter");
  223.         } catch(e) {
  224.         }
  225.         
  226.         if(preferred=="ffmpeg")
  227.             converterFile=ffmpegFile;
  228.         else
  229.             converterFile=mencoderFile;
  230.     }
  231.     
  232.     var dEntry={
  233.         file: converterFile,
  234.         qRes: convRes,
  235.         autoClear: autoClear,
  236.         sourceFile: sourceFile,
  237.         targetFile: targetFile,
  238.         convConf: extension+"/"+params,
  239.         listener: listener,
  240.         entry: entry,
  241.         ctx: ctx
  242.     }
  243.     
  244.     if(converterFile==ffmpegFile) {
  245.         this.setFFMPEGArgs(dEntry,params,sourceFile,targetFile,false,false);
  246.     }
  247.     if(converterFile==mencoderFile) {
  248.         dEntry.args = [ sourceFile.path ];
  249.         // adjust depending on bitrate
  250.         dEntry.args=dEntry.args.concat(["-oac", "copy", "-ovc", "copy"]);            
  251.         dEntry.args=dEntry.args.concat(["-o", targetFile.path]);
  252.     }
  253.     
  254.     this.delayQueue.push(dEntry);
  255.     this.checkConvert();
  256. }
  257.  
  258. ConvertMgr.prototype.escapePath=function(path) {
  259.     path=path.replace(/\\/g,"\\\\");
  260.     path=path.replace(/ /g,"\\ ");
  261.     path=path.replace(/"/g,"\\\"");
  262.     return path;
  263. }
  264.  
  265. ConvertMgr.prototype.convertDH=function(sourceFile,targetFile,params,extension,convRes,autoClear,listener,entry,ctx) {
  266.  
  267.     try {
  268.  
  269.     var file=this.getInstallDir();
  270.     file.append("cvhelper.exe");
  271.  
  272.     var unreg=this.updateUnregistered();
  273.     
  274.     var dEntry={
  275.         file: file,
  276.         qRes: convRes,
  277.         autoClear: autoClear,
  278.         sourceFile: sourceFile,
  279.         targetFile: targetFile,
  280.         convConf: extension+"/"+params,
  281.         listener: listener,
  282.         entry: entry,
  283.         ctx: ctx
  284.     }
  285.  
  286.     this.setFFMPEGArgs(dEntry,params,sourceFile,targetFile,true,unreg);
  287.  
  288.     this.delayQueue.push(dEntry);
  289.     this.checkConvert();
  290.     
  291.     } catch(e) {
  292.         dump("!!! [ConvertMgr] convertDH: "+e+"\n");
  293.     }
  294. }
  295.  
  296. ConvertMgr.prototype.execConvert=function(dEntry) {
  297.     this.currentEntry=dEntry;
  298.     Util.setPropertyValueRS(this.queueDatasource,dEntry.qRes,DHNS+"Status","3");
  299.     Util.setPropertyValueRS(this.queueDatasource,dEntry.qRes,DHNS+"ProgressMode","undetermined");
  300.     var Processor=function(convMgr,dEntry) {
  301.         try {
  302.             this.dEntry=dEntry;
  303.             var proxyMgr = Components. classes["@mozilla.org/xpcomproxy;1"].getService(Components.interfaces.nsIProxyObjectManager);
  304.             var proxyFlags = Components.interfaces.nsIProxyObjectManager.FORCE_PROXY_CREATION |
  305.                 Components.interfaces.nsIProxyObjectManager.INVOKE_SYNC;
  306.             this.convMgr=proxyMgr.getProxyForObject(null/*uiQueue*/,Components.interfaces.dhIConvertMgr, convMgr, proxyFlags );
  307.         } catch(e) {
  308.             dump("!!![ConvertMgr/Processor] constructor: "+e+"\n");
  309.         }
  310.     }
  311.     Processor.prototype={
  312.         run: function() {
  313.             //dump("[ConvertMgr/Processor] execConvert [run]\n");
  314.             try {
  315.                 var result=false;
  316.                 if(this.dEntry.args2) {
  317.                     var file = Components.classes["@mozilla.org/file/directory_service;1"]
  318.                                          .getService(Components.interfaces.nsIProperties)
  319.                                          .get("TmpD", Components.interfaces.nsIFile);
  320.                     file.append("passlogfile.tmp");
  321.                     file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
  322.                     var r=this.convertPass(["-pass","1","-passlogfile",file.path].concat(this.dEntry.args),false);
  323.                     if(r) {
  324.                         result=this.convertPass(["-pass","2","-passlogfile",file.path].concat(this.dEntry.args2),true);
  325.                     }
  326.                     if(file.exists())
  327.                         file.remove(false);
  328.                 } else {
  329.                     result=this.convertPass(this.dEntry.args,true);
  330.                 }
  331.                 this.convMgr.scheduleNext(result);
  332.             } catch(e) {
  333.                 dump("!!! [ConvertMgr/Processor] execConvert [run]: "+e+"\n");
  334.             }
  335.         },
  336.         convertPass: function(args,lastPass) {
  337.             var process = Components.classes["@mozilla.org/process/util;1"]
  338.                                 .createInstance(Components.interfaces.nsIProcess);
  339.             process.init(this.dEntry.file);
  340.  
  341.             process.run(true, args, args.length,{});
  342.             
  343.             var success;
  344.             if(process.exitValue==0) {
  345.                 success=true;
  346.                 if(lastPass && this.dEntry.autoClear) {
  347.                     var keepOriginal=false;
  348.                     try {
  349.                         keepOriginal=this.pref.getBoolPref("convert.keep-original");
  350.                     } catch(e) {}
  351.                     if(!keepOriginal)
  352.                         this.dEntry.sourceFile.remove(false);
  353.                 }
  354.             } else {
  355.                 success=false;
  356.                 if(this.dEntry.autoClear) {
  357.                     try {
  358.                         this.dEntry.targetFile.remove(false);
  359.                     } catch(e) {
  360.                         dump("!!! [ConvertMgr/Processor] execConvert [run] failed: "+e+"\n");
  361.                     }
  362.                     var keepOriginalOnFailure=true;
  363.                     try {
  364.                         keepOriginalOnFailure=this.pref.getBoolPref("convert.keep-original-on-failure");
  365.                     } catch(e) {}
  366.                     if(keepOriginalOnFailure) {
  367.                         var filename=this.dEntry.sourceFile.leafName;
  368.                         var recoveryLeafName=null;
  369.                         if(/^.+\..*$/.test(filename)) {
  370.                             var m=/^(.+)\.(.*)$/.exec(filename);
  371.                             recoveryLeafName=m[1]+".failed-conv."+m[2];
  372.                         } else {
  373.                             recoveryLeafName=filename+".failed-conv";
  374.                         }
  375.                         var recoveryFile=this.dEntry.targetFile.parent;
  376.                         recoveryFile.append(recoveryLeafName);
  377.                         recoveryFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0644);
  378.                         this.dEntry.sourceFile.moveTo(this.dEntry.targetFile.parent,recoveryFile.leafName);
  379.                     }
  380.                 }
  381.             }
  382.             return success;
  383.         },
  384.         QueryInterface: function(iid) {
  385.             if (iid.equals(Components.interfaces.nsIRunnable) ||
  386.                 iid.equals(Components.interfaces.nsISupports)) {
  387.                 return this;
  388.             }
  389.             throw Components.results.NS_ERROR_NO_INTERFACE;
  390.         }
  391.         
  392.     }
  393.     try {
  394.         var thread = Components.classes["@mozilla.org/thread;1"].createInstance(Components.interfaces.nsIThread);
  395.         thread.init(
  396.                 new Processor(this,dEntry),
  397.                 0,
  398.                 Components.interfaces.nsIThread.PRIORITY_LOW,
  399.                 Components.interfaces.nsIThread.SCOPE_LOCAL,
  400.                 Components.interfaces.nsIThread.STATE_UNJOINABLE
  401.                 );
  402.     } catch(e) {
  403.         try {
  404.             //dump("!!! [ConvertMgr/Processor] execConvert [creating thread]: "+e+"\n");
  405.             var threadMgr = Components.classes["@mozilla.org/thread-manager;1"].getService();
  406.             var thread=threadMgr.newThread(0);
  407.             thread.dispatch(new Processor(this,dEntry),thread.DISPATCH_NORMAL);
  408.             //dump("[ConvertMgr/Processor] execConvert [dispatched]\n");
  409.         } catch(e) {
  410.             dump("!!! [ConvertMgr/Processor] execConvert [dispatching]: "+e+"\n");
  411.         }
  412.     }
  413. }
  414.  
  415. ConvertMgr.prototype.checkConvert=function() {
  416.     try {
  417.         if(this.delayQueue.length>0 && this.currentEntry==null) {
  418.             var dEntry=this.delayQueue.shift();
  419.             this.execConvert(dEntry);
  420.         }
  421.     } catch(e) {
  422.         dump("!!! [ConvertMgr] checkConvert(): "+e+"\n");
  423.     }
  424. }
  425.  
  426. ConvertMgr.prototype.addConvert=function(sourceFile,targetFile,format,autoClear,listener,entry,ctx) {
  427.  
  428.     //dump("[ConvertMgr] addConvert("+sourceFile.path+","+targetFile.path+","+format+")\n");
  429.  
  430.     if(!this.isEnabled())
  431.         return;
  432.     this.convert(sourceFile,targetFile,format,autoClear,listener,entry,ctx);
  433. }
  434.  
  435. ConvertMgr.prototype.getFormat=function(filename,mediaUrl,pageUrl) {
  436.  
  437.     //dump("[ConvertMgr] getFormat("+filename+","+mediaUrl+","+pageUrl+")\n");
  438.  
  439.     if(!this.isEnabled()) {
  440.         //dump("[ConvertMgr] getFormat(): convert not enabled\n");
  441.         return null;
  442.     }
  443.     var extension=null;
  444.     try {
  445.         extension=/.*\.(.*?)$/.exec(filename)[1];
  446.     } catch(e) {
  447.         dump("!!! [ConvertMgr] getFormat(): no extension from "+filename+"\n");
  448.         return null;
  449.     }
  450.     try {
  451.     var rules=Util.getChildResourcesS(this.datasource,"urn:root",{});
  452.     for(var i=0;i<rules.length;i++) {
  453.         var infile=Util.getPropertyValueRS(this.datasource,rules[i],DHNS+"infile");
  454.         if(infile=="" || infile.toLowerCase()==extension.toLowerCase()) {
  455.             var insite=Util.getPropertyValueRS(this.datasource,rules[i],DHNS+"insite");
  456.             var re=new RegExp("https?://(?:[^/]*\\.)?"+insite+"/.*","i");
  457.             if(insite=="" || re.test(mediaUrl) || (pageUrl!=null && re.test(pageUrl))) {
  458.                 var action=Util.getPropertyValueRS(this.datasource,rules[i],DHNS+"action");
  459.                 if(action=="0") {
  460.                     //dump("[ConvertMgr] getFormat(): explicit no conversion\n");
  461.                     return null;
  462.                 } else {
  463.                     var format=Util.getPropertyValueRS(this.datasource,rules[i],DHNS+"outformat");
  464.                     //dump("[ConvertMgr] getFormat(): format="+format+"\n");
  465.                     return format;
  466.                 }
  467.             }
  468.         }
  469.     }
  470.     return null;
  471.     } catch(e) {
  472.         dump("!!! [ConvertMgr] getFormat(): "+e+"\n");
  473.         return null;
  474.     }
  475. }
  476.  
  477. ConvertMgr.prototype.getDataSource=function() {
  478.     //dump("[ConvertMgr] getDataSource()\n");
  479.     return this.datasource;
  480. }
  481.  
  482. ConvertMgr.prototype.setDataSource=function(datasource) {
  483.     //dump("[ConvertMgr] setDataSource()\n");
  484.     try {
  485.         var serializer="@mozilla.org/rdf/xml-serializer;1";
  486.         var s=Components.classes[serializer].createInstance(Components.interfaces.nsIRDFXMLSerializer);
  487.         s.init(datasource);
  488.         var stream = Components.classes['@mozilla.org/network/file-output-stream;1']
  489.             .createInstance(Components.interfaces.nsIFileOutputStream);
  490.         stream.init(this.convRulesFile, 42, 0644, 0); 
  491.     
  492.         s.QueryInterface(Components.interfaces.nsIRDFXMLSource).Serialize(stream);
  493.         stream.close();
  494.     } catch(e) {
  495.         dump("!!! [ConvertMgr] setDataSource: "+e+"\n");
  496.     }
  497.     this.datasource=datasource;
  498. }
  499.  
  500. ConvertMgr.prototype.getDataSourceCopy=function() {
  501.     //dump("[ConvertMgr] getDataSourceCopy()\n");
  502.     var datasource=Util.getDatasourceFromRDFFile(this.convRulesFile);
  503.     return datasource;
  504. }
  505.  
  506. ConvertMgr.prototype.makeDefaultRule=function(datasource) {
  507.     //dump("[ConvertMgr] makeDefaultRule()\n");
  508.     var defRule=Util.createAnonymousNodeS(datasource,"urn:root");
  509.     Util.setPropertyValueRS(datasource,defRule,DHNS+"label",Util.getText("conversion.default-rule-label"));
  510.     Util.setPropertyValueRS(datasource,defRule,DHNS+"action","1");
  511.     Util.setPropertyValueRS(datasource,defRule,DHNS+"infile","flv");
  512.     Util.setPropertyValueRS(datasource,defRule,DHNS+"insite","");
  513.     Util.setPropertyValueRS(datasource,defRule,DHNS+"outformat","wmv/-acodec wmav1 -b 1000kbps -f asf -vcodec wmv1");
  514.     Util.setPropertyValueRS(datasource,defRule,DHNS+"outdir","");
  515.     Util.setPropertyValueRS(datasource,defRule,DHNS+"label",this.makeLabel(datasource,defRule.Value));
  516.     return defRule.Value;
  517. }
  518.  
  519. ConvertMgr.prototype.isEnabled=function() {
  520.     //dump("[ConvertMgr] isEnabled()\n");
  521.     var enabled=false;
  522.     try {
  523.         enabled=this.pref.getBoolPref("conversion-enabled");
  524.     } catch(e) {}
  525.     return enabled;
  526. }
  527.  
  528. ConvertMgr.prototype.getInstallDir=function() {
  529.     //dump("[ConvertMgr] getInstallDir()\n");
  530.     try {
  531.         var wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
  532.                             .createInstance(Components.interfaces.nsIWindowsRegKey);
  533.         if(wrk==null) {
  534.             dump("!!![ConvertMgr] getInstallDir(): no registry service\n");
  535.             return null;
  536.         }
  537.         
  538.         var method=this.getConvMethod();
  539.         var regPath;
  540.         if(method==CONV_METHOD_WIN_DH)
  541.             regPath="SOFTWARE\\DownloadHelper\\ConvertHelper";
  542.         else {
  543.             dump("!!![ConvertMgr] getInstallDir(): no path available\n");
  544.             return null;
  545.         }
  546.         var r=wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
  547.                  regPath,
  548.                  wrk.ACCESS_READ);
  549.         //dump("[ConvertMgr] getExePath(): open returns "+r+"\n");
  550.         var folderPath = wrk.readStringValue("InstallFolder");
  551.         wrk.close();
  552.         //dump("*** "+folderPath+"\n");
  553.         if(folderPath==null)
  554.             return null;
  555.         var file = Components.classes["@mozilla.org/file/local;1"]
  556.                              .createInstance(Components.interfaces.nsILocalFile);
  557.         file.initWithPath(folderPath);
  558.         if(!file.exists()) {
  559.             dump("!!![ConvertMgr] getInstallDir(): "+folderPath+" does not exist\n");
  560.             return;
  561.         }
  562.         if(!file.isDirectory()) {
  563.             dump("!!![ConvertMgr] getInstallDir(): "+folderPath+" is not a directory\n");
  564.             return;
  565.         }
  566.         if(!file.isReadable()) {
  567.             dump("!!![ConvertMgr] getInstallDir(): "+folderPath+" is not readable\n");
  568.             return;
  569.         }
  570.         return file;
  571.         
  572.     } catch(e) {
  573.         dump("!!![ConvertMgr] getInstallDir():"+e+"\n");
  574.         return null;
  575.     }
  576. }
  577.  
  578. ConvertMgr.prototype.clearDataSource=function(datasource) {
  579.     var i = datasource.GetAllResources();
  580.     datasource.beginUpdateBatch();
  581.     while(i.hasMoreElements()) {
  582.         var source = i.getNext();
  583.         var j = datasource.ArcLabelsOut(source);
  584.         while(j.hasMoreElements()) {
  585.             var predicate = j.getNext();
  586.             var k = datasource.GetTargets(source,predicate,true);
  587.             while(k.hasMoreElements()) {
  588.                 var target = k.getNext();
  589.                 datasource.Unassert(source,predicate,target);
  590.             }
  591.         }
  592.     }
  593.     datasource.endUpdateBatch();    
  594. }
  595.  
  596. ConvertMgr.prototype.makeEmptyDataSource=function(datasource) {
  597.     this.clearDataSource(datasource);
  598. }
  599.  
  600. ConvertMgr.prototype.makeDefaultDataSource=function(datasource) {
  601.     this.clearDataSource(datasource);
  602.     this.makeDefaultRule(datasource);
  603. }
  604.  
  605. ConvertMgr.prototype.makeLabel=function(datasource,ref) {
  606.     try {
  607.     var action=Util.getPropertyValueSS(datasource,ref,
  608.         "http://downloadhelper.net/1.0#action");
  609.     var insite=Util.getPropertyValueSS(datasource,ref,
  610.         "http://downloadhelper.net/1.0#insite");
  611.     var infile=Util.getPropertyValueSS(datasource,ref,
  612.         "http://downloadhelper.net/1.0#infile");
  613.     var outformat=Util.getPropertyValueSS(datasource,ref,
  614.         "http://downloadhelper.net/1.0#outformat");
  615.     var outdir=Util.getPropertyValueSS(datasource,ref,
  616.         "http://downloadhelper.net/1.0#outdir");
  617.     
  618.     if(insite=="")
  619.         insite=Util.getText("label.conv-rule.all-sites");
  620.     if(infile=="")
  621.         infile=Util.getText("label.conv-rule.all-files");
  622.     if(outdir=="")
  623.         outdir=Util.getText("label.conv-rule.default-directory");
  624.     
  625.     var label;
  626.     if(action=="0") {
  627.         label=Util.getFText("label.conv-rule.label.do-not-convert",[
  628.             infile, insite
  629.         ],2);
  630.     } else {
  631.         var format=/^(.*?)\/.*$/.exec(outformat)[1];
  632.         label=Util.getFText("label.conv-rule.label.convert",[
  633.             infile, insite,
  634.             format.toUpperCase(),
  635.             outdir
  636.         ],4);
  637.     }
  638.             
  639.     return label;
  640.         
  641.     } catch(e) {
  642.         return null;
  643.     }
  644. }
  645.  
  646. ConvertMgr.prototype.updateUnregistered = function() {
  647.     var cf=true;
  648.     
  649.     var method=this.getConvMethod();
  650.     if(this.isEnabled() && method==CONV_METHOD_WIN_DH) {
  651.         try {
  652.             var reg=Components.classes["@mozilla.org/windows-registry-key;1"]
  653.                 .createInstance(Components.interfaces.nsIWindowsRegKey);
  654.             try {
  655.                 reg.open(reg.ROOT_KEY_CURRENT_USER,
  656.                              "SOFTWARE\\DownloadHelper\\ConvertHelper",
  657.                              reg.ACCESS_READ);
  658.                 var name=reg.readStringValue("CustomerName");
  659.                 var email=reg.readStringValue("CustomerEmail");
  660.                 var key=reg.readStringValue("LicenseKey");
  661.                 var licenseCheck=this.md5("converthelper"+key+name+email);
  662.                 var licenseCheck0=reg.readStringValue("LicenseCheck");
  663.                 reg.close();
  664.                 if(licenseCheck==licenseCheck0) { 
  665.                     var profile=Util.getProfileDir().leafName;
  666.                     var profileCheck=this.md5("converthelper"+profile);
  667.                     var profileCheck0="";
  668.                     try {
  669.                         profileCheck0=this.pref.getCharPref("converthelper-key");
  670.                     } catch(e) {}
  671.                     if(profileCheck!=profileCheck0) {
  672.                         this.checkLicense(key);
  673.                     } else {
  674.                         cf=false;
  675.                     }
  676.                 }    
  677.             } catch(e) { 
  678.                 //dump("!!![ConvertMgr] updateUnregistered: "+e+"\n"); 
  679.             }
  680.             try {
  681.                 reg.close();
  682.             } catch(e) {}
  683.         } catch(e) { 
  684.             cf=false; 
  685.         }
  686.     } else if(method==CONV_METHOD_UNIX) {
  687.         cf=false;
  688.     }
  689.  
  690.     this.pref.setBoolPref("convert-free",cf);
  691.     
  692.     return cf;
  693. }
  694.  
  695. ConvertMgr.prototype.register = function(code) {
  696.  
  697.     //dump("register: "+code+"\n");
  698.  
  699.  
  700.     var method=this.getConvMethod();
  701.     if(method==CONV_METHOD_WIN_DH) {
  702.         try {
  703.             this.checkLicense(code);
  704.         } catch(e) {
  705.             //dump("register exception: "+e+"\n");
  706.         }
  707.     }
  708. }
  709.  
  710. ConvertMgr.prototype.getConvMethod = function() {
  711.     var method=CONV_METHOD_NONE;
  712.     try {
  713.         var reg = Components.classes["@mozilla.org/windows-registry-key;1"]
  714.                             .createInstance(Components.interfaces.nsIWindowsRegKey);
  715.         method=CONV_METHOD_WIN_DH;
  716.     } catch(e) {
  717.         return CONV_METHOD_UNIX;
  718.     }
  719.     return method;
  720. }
  721.  
  722. ConvertMgr.prototype.checkLicense = function(key) {
  723.     
  724.     function XMLStreamListener(service) {
  725.         this.service=service;
  726.     }
  727.     
  728.     XMLStreamListener.prototype={
  729.         QueryInterface: function(iid) {
  730.             if (!iid.equals(Components.interfaces.nsISupports) && 
  731.                 !iid.equals(Components.interfaces.nsIStreamListener)) {
  732.                     throw Components.results.NS_ERROR_NO_INTERFACE;
  733.                 }
  734.             return this;
  735.         },
  736.         onStartRequest: function(request,context) {
  737.             this.data="";
  738.         },
  739.         onDataAvailable: function(request,context,inputStream,offset,count) {
  740.             var sstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
  741.                    .createInstance(Components.interfaces.nsIConverterInputStream);
  742.             sstream.init(inputStream, "utf-8", 256, 
  743.                 Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  744.     
  745.             var str={};
  746.             var n=sstream.readString(128,str);
  747.             while(n>0) {
  748.                 this.data+=str.value;
  749.                 str={};
  750.                 n=sstream.readString(128,str);
  751.             }
  752.         },
  753.         onStopRequest: function(request,context,nsresult) {
  754.             var responseStatus=request.QueryInterface(Components.interfaces.nsIHttpChannel).responseStatus;
  755.             if(responseStatus==200) {
  756.                 try {
  757.                     var parser=Components.classes["@mozilla.org/xmlextras/domparser;1"].
  758.                         createInstance(Components.interfaces.nsIDOMParser);
  759.                     var doc=parser.parseFromString(this.data,"text/xml");
  760.                     var xml=doc.documentElement;
  761.                     var status=Util.xpGetString(xml,"/check-license-response/status/text()");
  762.                     var name=Util.xpGetString(xml,"/check-license-response/name/text()");
  763.                     var email=Util.xpGetString(xml,"/check-license-response/email/text()");
  764.                     if(status=="accepted") {
  765.                         var reg = Components.classes["@mozilla.org/windows-registry-key;1"]
  766.                             .createInstance(Components.interfaces.nsIWindowsRegKey);
  767.                         reg.open(reg.ROOT_KEY_CURRENT_USER,
  768.                              "SOFTWARE",
  769.                              reg.ACCESS_ALL);
  770.                         reg=reg.createChild("DownloadHelper\\ConvertHelper",
  771.                              reg.ACCESS_ALL);
  772.                         var existingKey=null;
  773.                         try {
  774.                             existingKey=reg.readStringValue("LicenseKey");
  775.                         } catch(e) {}
  776.                         reg.writeStringValue("CustomerName",name);
  777.                         reg.writeStringValue("CustomerEmail",email);
  778.                         reg.writeStringValue("LicenseKey",key);
  779.                         var licenseCheck=this.service.md5("converthelper"+key+name+email);
  780.                         reg.writeStringValue("LicenseCheck",licenseCheck);
  781.                         reg.close();
  782.                         var profile=Util.getProfileDir().leafName;
  783.                         var profileCheck=this.service.md5("converthelper"+profile);
  784.                         this.service.pref.setCharPref("converthelper-key",profileCheck);
  785.                         this.service.updateUnregistered();
  786.                         if(existingKey==null) {
  787.                             this.service.promptService.alert(null,Util.getText("title.converter-registration"),
  788.                                 Util.getText("message.converter-registration-succeeded"));
  789.                         }
  790.                     } else if(status=="need-validation") {
  791.                         this.service.promptService.alert(null,Util.getText("title.converthelper.revalidate"),
  792.                             Util.getFText("message.converthelper.revalidate",
  793.                                 [name,email],2));
  794.                     } else {
  795.                         this.service.promptService.alert(null,Util.getText("title.converthelper.invalid-license"),
  796.                             Util.getText("message.converthelper.invalid-license"));
  797.                     }
  798.                 } catch(e) {
  799.                     dump("!!! [ConvertMgr] checkLicense: "+e+"\n"); 
  800.                 }
  801.             } else {
  802.                 dump("!!! [ConvertMgr] checkLicense: response "+responseStatus+"\n"); 
  803.             }
  804.         }
  805.     }
  806.     var body="<check-license>\n"+
  807.         "  <license-key>"+key+"</license-key>\n"+
  808.         "  <product>converthelper</product>\n"+
  809.         "</check-license>";
  810.     var ios=Components.classes["@mozilla.org/network/io-service;1"]
  811.                                .getService(Components.interfaces.nsIIOService);
  812.     var uri = ios.newURI("http://www.downloadhelper.net/license-check.php", null, null);
  813.     var channel = ios.newChannelFromURI(uri);
  814.     var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel);
  815.     httpChannel.requestMethod = "POST";
  816.     var datais = Components.classes["@mozilla.org/io/string-input-stream;1"]
  817.                                     .createInstance(Components.interfaces.nsIStringInputStream);
  818.     datais.setData(body, body.length);
  819.     var uploadChannel = channel.QueryInterface(Components.interfaces.nsIUploadChannel);
  820.     uploadChannel.setUploadStream(datais, "application/x-binary", -1);
  821.     var listener = new XMLStreamListener(this);
  822.     channel.notificationCallbacks = listener;
  823.     channel.asyncOpen(listener, null);
  824. }
  825.  
  826. ConvertMgr.prototype.md5 = function(str) {
  827.     var converter =
  828.       Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
  829.         createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  830.     
  831.     converter.charset = "UTF-8";
  832.     var result = {};
  833.     var data = converter.convertToByteArray(str, result);
  834.     var ch = Components.classes["@mozilla.org/security/hash;1"]
  835.                        .createInstance(Components.interfaces.nsICryptoHash);
  836.     ch.init(ch.MD5);
  837.     ch.update(data, data.length);
  838.     var hash = ch.finish(false);
  839.     
  840.     function toHexString(charCode)
  841.     {
  842.       return ("0" + charCode.toString(16)).slice(-2);
  843.     }
  844.     
  845.     var t=[];
  846.     for(var i in hash) {
  847.         t.push(toHexString(hash.charCodeAt(i)));
  848.     }
  849.     var s=t.join("");
  850.     
  851.     return s;
  852. }
  853.  
  854. ConvertMgr.prototype.getInfo = function() {
  855.  
  856.     this.updateUnregistered();
  857.  
  858.     var props = Components.classes["@mozilla.org/properties;1"].createInstance(Components.interfaces.nsIProperties);
  859.  
  860.     var enabled=false;
  861.     try {
  862.         enabled=this.pref.getBoolPref("conversion-enabled");
  863.     } catch(e) {}
  864.     var sEnabled = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  865.     sEnabled.data=enabled;
  866.     props.set("enabled",sEnabled);
  867.  
  868.     var method=this.getConvMethod();
  869.     var sMethod = Components.classes["@mozilla.org/supports-PRInt32;1"].createInstance(Components.interfaces.nsISupportsPRInt32);
  870.     sMethod.data=method;
  871.     props.set("method",sMethod);
  872.  
  873.     var unregistered=true;
  874.     try {
  875.         unregistered=this.pref.getBoolPref("convert-free");
  876.     } catch(e) {}
  877.     var sUnregistered = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  878.     sUnregistered.data=unregistered;
  879.     props.set("unregistered",sUnregistered);
  880.  
  881.     if(method==CONV_METHOD_WIN_DH) {
  882.  
  883.         var exeFound=false;            
  884.         var reg=Components.classes["@mozilla.org/windows-registry-key;1"]
  885.             .createInstance(Components.interfaces.nsIWindowsRegKey);
  886.         try {
  887.             reg.open(reg.ROOT_KEY_LOCAL_MACHINE,
  888.                          "SOFTWARE\\DownloadHelper\\ConvertHelper",
  889.                          reg.ACCESS_READ);
  890.  
  891.             try {
  892.                 var folderPath = reg.readStringValue("InstallFolder");
  893.                 var file = Components.classes["@mozilla.org/file/local;1"]
  894.                                      .createInstance(Components.interfaces.nsILocalFile);
  895.                 file.initWithPath(folderPath);
  896.                 file.append("cvhelper.exe");
  897.                 if(file.exists()) {
  898.                     exeFound=true;
  899.                 }
  900.             } catch(e) {}
  901.             
  902.             try {
  903.                 var version = reg.readStringValue("Version");
  904.                 var sVersion = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  905.                 sVersion.data=version;
  906.                 props.set("converterversion",sVersion);
  907.             } catch(e) {}
  908.  
  909.             try {
  910.                 var sVersion = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  911.                 sVersion.data="2.0";
  912.                 props.set("converterminversion",sVersion);
  913.             } catch(e) {}
  914.  
  915.             reg.close();
  916.  
  917.             reg.open(reg.ROOT_KEY_CURRENT_USER,
  918.                          "SOFTWARE\\DownloadHelper\\ConvertHelper",
  919.                          reg.ACCESS_READ);
  920.             
  921.             if(unregistered==false) {
  922.  
  923.                 var name=reg.readStringValue("CustomerName");
  924.                 var email=reg.readStringValue("CustomerEmail");
  925.                 var key=reg.readStringValue("LicenseKey");
  926.     
  927.                 var sName = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  928.                 sName.data=name;
  929.                 props.set("customername",sName);
  930.     
  931.                 var sEmail = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  932.                 sEmail.data=email;
  933.                 props.set("customeremail",sEmail);
  934.     
  935.                 var sLicense = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  936.                 sLicense.data=key;
  937.                 props.set("license",sLicense);
  938.             }
  939.         } catch(e) {}
  940.  
  941.         var sExeFound = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  942.         sExeFound.data=exeFound;
  943.         props.set("exefound",sExeFound);
  944.  
  945.         try {
  946.             reg.close();
  947.         } catch(e) {}
  948.     }
  949.  
  950.     var windows=false;
  951.     try {
  952.         var reg=Components.classes["@mozilla.org/windows-registry-key;1"]
  953.             .createInstance(Components.interfaces.nsIWindowsRegKey);
  954.         windows=true;
  955.     } catch(e) {}
  956.     var sWindows = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  957.     sWindows.data=windows;
  958.     props.set("windows",sWindows);
  959.  
  960.     if(!windows) {
  961.         var exeFound=false;
  962.         var encoder="ffmpeg";
  963.         try {
  964.             encoder=this.pref.getCharPref("preferred-converter");
  965.         } catch(e) {}
  966.         try {
  967.             var encoderFile = Components.classes["@mozilla.org/file/local;1"]
  968.                                                  .createInstance(Components.interfaces.nsILocalFile);
  969.             encoderFile.initWithPath(this.pref.getCharPref("converter-path-"+encoder));
  970.             if(encoderFile.exists()) {
  971.                 exeFound=true;
  972.             }
  973.         } catch(e) {}
  974.         var sExeFound = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  975.         sExeFound.data=exeFound;
  976.         props.set("exefound",sExeFound);
  977.     }
  978.     
  979.     return props;
  980. }
  981.  
  982. ConvertMgr.prototype.getQueueDataSource = function() {
  983.     return this.queueDatasource;
  984. }
  985.  
  986. ConvertMgr.prototype.checkConverterVersion = function() {
  987.     var props=this.getInfo();
  988.     var version="1.0";
  989.     try {
  990.         version=props.get("converterversion",Components.interfaces.nsISupportsString).data;
  991.     } catch(e) {}
  992.     var minVersion="1.0";
  993.     try {
  994.         minVersion=props.get("converterminversion",Components.interfaces.nsISupportsString).data;
  995.     } catch(e) {}
  996.     if(parseFloat(version)<parseFloat(minVersion)) {
  997.         var r=this.promptService.confirm(null,Util.getText("error.convert-helper.version.title"),
  998.             Util.getFText("error.convert-helper.version",[version,minVersion],2));
  999.         if(r) {
  1000.             var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService().
  1001.                 QueryInterface(Components.interfaces.nsIWindowWatcher);
  1002.             wwatch.openWindow(null, "http://www.downloadhelper.net/install-converter.php",null,null,null);
  1003.         }
  1004.         return false;
  1005.     }
  1006.     return true;
  1007. }
  1008.  
  1009. ConvertMgr.prototype.scheduleNext = function(result) {
  1010.     if(result) {
  1011.         Util.setPropertyValueRS(this.queueDatasource,this.currentEntry.qRes,DHNS+"Status","4");
  1012.         Util.setPropertyValueRS(this.queueDatasource,this.currentEntry.qRes,DHNS+"EndDate",""+new Date());
  1013.         var cvcount=0;
  1014.         try {
  1015.             cvcount=this.pref.getIntPref("convert-count");
  1016.         } catch(e) {
  1017.         }
  1018.         cvcount++;
  1019.         this.pref.setIntPref("convert-count",cvcount);
  1020.         try {
  1021.             this.convConfShare(this.currentEntry.convConf);
  1022.         } catch(e) {
  1023.             dump("!!! [ConvertMgr] convConfShare: "+e+"\n");
  1024.         }
  1025.     } else {
  1026.         Util.setPropertyValueRS(this.queueDatasource,this.currentEntry.qRes,DHNS+"Status","5");
  1027.         Util.setPropertyValueRS(this.queueDatasource,this.currentEntry.qRes,DHNS+"EndDate",""+new Date());
  1028.         Util.setPropertyValueRS(this.queueDatasource,this.currentEntry.qRes,DHNS+"ErrorMessage","Converter error");
  1029.     }
  1030.     this.showNotification(this.currentEntry,result);
  1031.     if(this.currentEntry.listener) {
  1032.         try {
  1033.             this.currentEntry.listener.conversionFinished(result,this.currentEntry.entry,this.currentEntry.ctx);
  1034.         } catch(e) {
  1035.             dump("!!! [ConvertMgr] scheduleNext()/listener: "+e+"\n");
  1036.         }
  1037.     }
  1038.     this.currentEntry=null;
  1039.     this.checkConvert();
  1040. }
  1041.  
  1042. ConvertMgr.prototype.showNotification = function(entry,result) {
  1043.     try {
  1044.         var showNotification=true;
  1045.         try {
  1046.             showNotification=this.pref.getBoolPref("convert-helper.notification");
  1047.         } catch(e) {
  1048.         }
  1049.         if(showNotification) {
  1050.             var alertsService = Components.classes["@mozilla.org/alerts-service;1"]
  1051.                                 .getService(Components.interfaces.nsIAlertsService);
  1052.             var title=Util.getText("title.notif.conversion");
  1053.             var message;
  1054.             if(result)
  1055.                 message=Util.getFText("message.notif.conversion.success",[entry.targetFile.leafName],1);
  1056.             else
  1057.                 message=Util.getFText("message.notif.conversion.failure",[entry.targetFile.leafName],1);
  1058.             alertsService.showAlertNotification("chrome://dwhelper/skin/converter-16x16.png",
  1059.                 title,message);
  1060.         }
  1061.     } catch(e) {
  1062.         //dump("!!![ConvertMgr] showNotification: "+e+"\n");
  1063.     }
  1064. }
  1065.  
  1066. ConvertMgr.prototype.convConfShare = function(convConf) {
  1067.     var confs=Util.getChildResourcesS(this.localstore,DHNS+"conv-confs",{});
  1068.     var convCount=0;
  1069.     if(!isNaN(parseInt(Util.getPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"conv-count"))))
  1070.         convCount=parseInt(Util.getPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"conv-count"));
  1071.     convCount++;
  1072.     Util.setPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"conv-count",""+convCount);
  1073.     var shareStep=0;
  1074.     if(!isNaN(parseInt(Util.getPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"share-step"))))
  1075.         shareStep=parseInt(Util.getPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"share-step"));
  1076.     var doPublish=false;
  1077.     if(convCount>=10*Math.pow(2,shareStep)) {
  1078.         doPublish=true;
  1079.         Util.setPropertyValueSS(this.localstore,DHNS+"conv-confs",DHNS+"share-step",""+(shareStep+1));
  1080.     }
  1081.     var doShare=true;
  1082.     try {
  1083.         doShare=this.pref.getBoolPref("convert-helper.share-config");
  1084.     } catch(e) {}
  1085.     if(doShare==false)
  1086.         doPublish=false;
  1087.     var xml="<?xml version='1.0'?>\n<conversion-configs>\n";
  1088.     for(var i=0;i<confs.length;i++) {
  1089.         /* dump("Checking conf "+Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"label")+" = "+
  1090.                 Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"value")+"\n"); */
  1091.         var cnt=0;
  1092.         if(!isNaN(parseInt(Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"conv-count"))))
  1093.             cnt=parseInt(Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"conv-count"));
  1094.         var conf=Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"value");
  1095.         if(conf==convConf) {
  1096.             cnt++;
  1097.             Util.setPropertyValueRS(this.localstore,confs[i],DHNS+"conv-count",""+cnt);
  1098.         }
  1099.         if(cnt>=10) {
  1100.             xml+="  <conversion-config>\n";
  1101.             xml+="    <value>"+Util.xmlEscape(Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"value"))+"</value>\n";
  1102.             xml+="    <label>"+Util.xmlEscape(Util.getPropertyValueRS(this.localstore,confs[i],DHNS+"label"))+"</label>\n";
  1103.             xml+="    <count>"+cnt+"</count>\n";
  1104.             xml+="  </conversion-config>\n";
  1105.             Util.setPropertyValueRS(this.localstore,confs[i],DHNS+"conv-count","0");
  1106.         }
  1107.     }
  1108.     xml+="</conversion-configs>\n";
  1109.     if(doPublish) {
  1110.         var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
  1111.             createInstance(Components.interfaces.nsIXMLHttpRequest);
  1112.         xmlhttp.open ("POST", "http://www.downloadhelper.net/share-conv-confs.php")
  1113.         xmlhttp.send(xml);
  1114.     }
  1115. }
  1116.  
  1117. ConvertMgr.prototype.setDefaultConfigs = function() {
  1118.     var formats=[
  1119.                  {
  1120.                      value: 'mpg/-acodec mp2 -b 800kbps -f mpeg -r 24 -vcodec mpeg1video',
  1121.                      title: 'MPEG (mpeg1+mp2)'
  1122.                  },
  1123.                  {
  1124.                      value: 'wmv/-acodec wmav1 -b 1000kbps -f asf -vcodec wmv1',
  1125.                      title: 'WMV (Windows Media Player)'
  1126.                  },
  1127.                  {
  1128.                      value: 'm4v/-acodec libfaac -b 274kbps -f mp4 -r 24 -s 320x240 -vcodec mpeg4',
  1129.                      title: 'iPod'
  1130.                  },
  1131.                  {
  1132.                      value: 'm4v/-acodec libfaac -b 548kbps -f mp4 -r 24 -s 480x320 -vcodec mpeg4',
  1133.                      title: 'iPhone'
  1134.                  },
  1135.                  {
  1136.                      value: '3gp/-ab 12kbps -ac 1 -acodec libfaac -ar 8000 -b 64kbps -f 3gp -r 24 -s 176x144 -vcodec h263',
  1137.                      title: 'Mobile 3GP (Qcif)'
  1138.                  },
  1139.                  {
  1140.                      value: 'wmv/-ab 128000 -ac 2 -acodec wmav2 -b 640000 -bufsize 2048000 -f asf -maxrate 1350000 -s 320x240 -vcodec wmv2',
  1141.                      title: 'Zune'
  1142.                  },
  1143.                  {
  1144.                      value: 'mov/-f mov -sameq',
  1145.                      title: 'Quicktime (MOV)'
  1146.                  },
  1147.                  {
  1148.                      value: 'avi/-acodec libmp3lame -f avi -vcodec mpeg4',
  1149.                      title: 'AVI (mpeg4+mp3)'
  1150.                  },
  1151.                  {
  1152.                      value: 'mp4/-ac 2 -acodec libmp3lame -ar 44100 -f avi -vcodec mpeg4',
  1153.                      title: 'MPEG-4 '
  1154.                  },
  1155.                  {
  1156.                      value: 'mpeg/-f mpeg2video -target pal-dvd',
  1157.                      title: 'MPEG-2 DVD (PAL)'
  1158.                  },
  1159.                  {
  1160.                      value: 'mpeg/-f mpeg2video -target ntsc-dvd',
  1161.                      title: 'MPEG-2 DVD (NTSC)'
  1162.                  },
  1163.                  {
  1164.                      value: 'mp3/-ab 128k -f mp3',
  1165.                      title: 'MP3'
  1166.                  },
  1167.     ];
  1168.     this.localstore.beginUpdateBatch();
  1169.     if(Util.getPropertyResourceSS(this.localstore,DHNS+"conv-confs","http://www.w3.org/1999/02/22-rdf-syntax-ns#instanceOf")==null) {
  1170.         Util.createNodeRS(this.localstore,null,DHNS+"conv-confs");
  1171.     } 
  1172.     var convConfs=DHNS+"conv-confs";
  1173.     for(var i=0;i<formats.length;i++) {
  1174.         var format=formats[i];
  1175.         var convConf=Util.createNodeSS(this.localstore,convConfs,null);
  1176.         Util.setPropertyValueRS(this.localstore,convConf,DHNS+"value",format.value);
  1177.         Util.setPropertyValueRS(this.localstore,convConf,DHNS+"label",format.title);
  1178.     }
  1179.     this.localstore.endUpdateBatch();
  1180. }
  1181.  
  1182. ConvertMgr.prototype.clearConfigs = function(full) {
  1183.     this.localstore.beginUpdateBatch();
  1184.     var confs=Util.getChildResourcesS(this.localstore,DHNS+"conv-confs",{});
  1185.     for(var i=0;i<confs.length;i++) {
  1186.         Util.removeReference(this.localstore,confs[i]);
  1187.     }
  1188.     if(full)
  1189.         Util.removeReferenceS(this.localstore,DHNS+"conv-confs");
  1190.     this.localstore.endUpdateBatch();
  1191. }
  1192.  
  1193. ConvertMgr.prototype.getConvertedFileName = function(filename,format) {
  1194.     var extension=null;
  1195.     if(format!=null && /^.+\/.*/.test(format))
  1196.         extension=/^(.+?)\/.*$/.exec(format)[1];
  1197.     if(extension!=null) {
  1198.         if(/^.+\..+$/.test(filename)) {
  1199.             filename=/^(.+\.)[^\.]{1,5}$/.exec(filename)[1]+extension;
  1200.         } else {
  1201.             filename=filename+"."+extension;
  1202.         }
  1203.     }
  1204.     return filename;
  1205. }
  1206.  
  1207. ConvertMgr.prototype.checkConverter= function(interactive) {
  1208.     //dump("[ConvertMgr] checkConverter()\n");
  1209.     var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  1210.                                 .getService(Components.interfaces.nsIWindowMediator);
  1211.     var window = wm.getMostRecentWindow("navigator:browser");
  1212.     var info=this.getInfo();
  1213.     while(info.get("enabled",Components.interfaces.nsISupportsPRBool).data==false || 
  1214.             info.get("exefound",Components.interfaces.nsISupportsPRBool).data==false) {
  1215.         if(!interactive)
  1216.             return false;
  1217.         var msgTag="";
  1218.         if(info.get("enabled",Components.interfaces.nsISupportsPRBool).data==false)
  1219.             msgTag="confirm.conversion-not-enabled.configure";
  1220.         else if(info.get("exefound",Components.interfaces.nsISupportsPRBool).data==false)
  1221.             msgTag="confirm.converter-not-found.configure";
  1222.         var rc=window.confirm(Util.getText(msgTag));
  1223.         if(!rc)
  1224.             return false;
  1225.         var options="chrome,centerscreen,titlebar,toolbar,modal";
  1226.         var data={ selectedPanel: "panel-conversion" }
  1227.         window.openDialog("chrome://dwhelper/content/preferences-new.xul",'_blank',options, data );
  1228.         info=this.getInfo();
  1229.     }
  1230.     //dump("[ConvertMgr] checkConverter() => true\n");
  1231.     return true;
  1232. }
  1233.  
  1234. ConvertMgr.prototype.QueryInterface = function(iid) {
  1235.     if(
  1236.         iid.equals(Components.interfaces.dhIConvertMgr)==false &&
  1237.         iid.equals(Components.interfaces.nsISupports)==false
  1238.     ) {
  1239.             throw Components.results.NS_ERROR_NO_INTERFACE;
  1240.         }
  1241.     return this;
  1242. }
  1243.  
  1244. var vConvertMgrModule = {
  1245.     firstTime: true,
  1246.     
  1247.     /*
  1248.      * RegisterSelf is called at registration time (component installation
  1249.      * or the only-until-release startup autoregistration) and is responsible
  1250.      * for notifying the component manager of all components implemented in
  1251.      * this module.  The fileSpec, location and type parameters are mostly
  1252.      * opaque, and should be passed on to the registerComponent call
  1253.      * unmolested.
  1254.      */
  1255.     registerSelf: function (compMgr, fileSpec, location, type) {
  1256.  
  1257.         if (this.firstTime) {
  1258.             this.firstTime = false;
  1259.             throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  1260.         }
  1261.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1262.         compMgr.registerFactoryLocation(NS_CONVERT_MGR_CID,
  1263.                                         "ConvertMgr",
  1264.                                         NS_CONVERT_MGR_PROG_ID, 
  1265.                                         fileSpec,
  1266.                                         location,
  1267.                                         type);
  1268.     },
  1269.  
  1270.     unregisterSelf: function(compMgr, fileSpec, location) {
  1271.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1272.         compMgr.unregisterFactoryLocation(NS_DH_CONVERT_MGR_CID, fileSpec);
  1273.     },
  1274.  
  1275.     /*
  1276.      * The GetClassObject method is responsible for producing Factory and
  1277.      * SingletonFactory objects (the latter are specialized for services).
  1278.      */
  1279.     getClassObject: function (compMgr, cid, iid) {
  1280.         if (!cid.equals(NS_CONVERT_MGR_CID)) {
  1281.             throw Components.results.NS_ERROR_NO_INTERFACE;
  1282.         }
  1283.  
  1284.         if (!iid.equals(Components.interfaces.nsIFactory)) {
  1285.             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  1286.         }
  1287.  
  1288.         return this.vConvertMgrFactory;
  1289.     },
  1290.  
  1291.     /* factory object */
  1292.     vConvertMgrFactory: {
  1293.         /*
  1294.          * Construct an instance of the interface specified by iid, possibly
  1295.          * aggregating it with the provided outer.  (If you don't know what
  1296.          * aggregation is all about, you don't need to.  It reduces even the
  1297.          * mightiest of XPCOM warriors to snivelling cowards.)
  1298.          */
  1299.         createInstance: function (outer, iid) {
  1300.             if (outer != null) {
  1301.                 throw Components.results.NS_ERROR_NO_AGGREGATION;
  1302.             }
  1303.     
  1304.             if(Util==null) 
  1305.                 Util=Components.classes["@downloadhelper.net/util-service;1"]
  1306.                     .getService(Components.interfaces.dhIUtilService);
  1307.  
  1308.             return new ConvertMgr().QueryInterface(iid);
  1309.         }
  1310.     },
  1311.  
  1312.     /*
  1313.      * The canUnload method signals that the component is about to be unloaded.
  1314.      * C++ components can return false to indicate that they don't wish to be
  1315.      * unloaded, but the return value from JS components' canUnload is ignored:
  1316.      * mark-and-sweep will keep everything around until it's no longer in use,
  1317.      * making unconditional ``unload'' safe.
  1318.      *
  1319.      * You still need to provide a (likely useless) canUnload method, though:
  1320.      * it's part of the nsIModule interface contract, and the JS loader _will_
  1321.      * call it.
  1322.      */
  1323.     canUnload: function(compMgr) {
  1324.         return true;
  1325.     }
  1326. };
  1327.  
  1328. function NSGetModule(compMgr, fileSpec) {
  1329.     return vConvertMgrModule;
  1330. }
  1331.  
  1332.